package br.com.sebrae.pr.sgp.dao.impl;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

import org.apache.commons.lang3.StringUtils;

import br.com.sebrae.pr.sgp.dao.ClienteDAO;
import br.com.sebrae.pr.sgp.dao.base.BaseDao;
import br.com.sebrae.pr.sgp.entities.Cliente;
import br.com.sebrae.pr.sgp.entities.Usuario;
import br.com.sebrae.pr.sgp.util.persistence.IConverter;
import br.com.sebrae.pr.sgp.util.persistence.ItemResultset;
import br.com.sebrae.pr.sgp.util.persistence.params.InParam;
import br.com.sebrae.pr.sgp.util.persistence.params.ParamType;

import com.google.common.base.Preconditions;

@Stateless
@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public class ClienteDaoImpl extends BaseDao implements ClienteDAO {

	@Override
	public Cliente pesquisarPorId(final long id) {
		final Cliente filtro = new Cliente();
		filtro.setId(id);
		final List<Cliente> ret = pesquisar(filtro);
		if (ret.iterator().hasNext()) {
			return ret.iterator().next();
		}
		return null;
	}

	@Override
	public Cliente pesquisarPorLogin(final String nmeLogin) {
		final Cliente filtro = new Cliente();
		filtro.setNome(nmeLogin);
		final List<Cliente> ret = pesquisar(filtro);
		if (ret.iterator().hasNext()) {
			return ret.iterator().next();
		}
		return null;
	}

	@Override
	public List<Cliente> efetuarPesquisa(final Cliente cliente) {
		return pesquisar(cliente, true);
	}

	/**
	 * Pesquisa os usuários utilizando os campos do {@link Usuario} parâmetro como filtros. Não utiliza like mas =
	 * 
	 * @see ClienteDaoImpl#pesquisar(Usuario, boolean)
	 * 
	 * @param filtro
	 * @return
	 */
	private List<Cliente> pesquisar(final Cliente filtro) {
		return pesquisar(filtro, false);
	}

	/**
	 * Pesquisa os usuários utilizando os campos do {@link Usuario} parâmetro como filtros. Utiliza LIKE se o parametro paraPesquisa = true
	 * 
	 * @param filtro
	 * @param paraPesquisa
	 * @return
	 */
	private List<Cliente> pesquisar(final Cliente filtro, final boolean paraPesquisa) {
		final List<InParam> params = new ArrayList<InParam>();

		final StringBuffer sql = new StringBuffer();
		sql.append("SELECT id, \n");
		sql.append("       nome_usuario \n");
		sql.append("  FROM usuario \n");
		sql.append(" WHERE 1 = 1 \n");
		if (filtro != null) {
			if (paraPesquisa) {
				if (StringUtils.isNotBlank(filtro.getNome())) {
					sql.append("   AND (UPPER(usuario.a1083_login) LIKE(?) OR UPPER(usuario.a1083_usr_svn) LIKE(?))\n");
					params.add(new InParam(params.size() + 1, "%" + filtro.getNome().toUpperCase() + "%", ParamType.VARCHAR));
					params.add(new InParam(params.size() + 1, "%" + filtro.getNome().toUpperCase() + "%", ParamType.VARCHAR));
				}
				if (StringUtils.isNotBlank(filtro.getNome())) {
					sql.append("   AND UPPER(ag.a0015_nm_agente) LIKE(?) \n");
					params.add(new InParam(params.size() + 1, "%" + filtro.getNome().toUpperCase() + "%", ParamType.VARCHAR));
				}

			} else {
				if (StringUtils.isNotBlank(filtro.getNome())) {
					sql.append("   AND nome_usuario = ? \n");
					params.add(new InParam(params.size() + 1, filtro.getNome(), ParamType.VARCHAR));
				}
			}
		}
		return executarQuery(sql, params, new IConverter<Cliente>() {

			@Override
			public Cliente convert(final ItemResultset reg) {
				final Cliente ret = new Cliente();
				ret.setId(reg.getLong("id"));
				ret.setNome(reg.getString("nome_usuario"));
				return ret;
			}
		});
	}

	@Override
	@TransactionAttribute(TransactionAttributeType.REQUIRED)
	public Cliente salvarOuAtualizar(final Cliente cliente) {
		Preconditions.checkNotNull(cliente, "Usuário é obrigatório e deve ser informado!");
		Preconditions.checkNotNull(cliente.getUsuarioLogado().getId(), "ID do usuário logado é obrigatório e deve ser informado!");
		final List<InParam> params = new ArrayList<InParam>();
		if (inclusao(cliente)) {
			throw new IllegalArgumentException("Inclusão de usuários não é contemplada no sistema!");

		} else {
			final StringBuffer sql = new StringBuffer();
			sql.append("UPDATE master.tb1083_vc_user \n");
			sql.append("   SET a1083_usr_svn = ?, \n");
			sql.append("       a1083_email = ?, \n");
			sql.append("       a1083_passwd_md5 = ?, \n");
			sql.append("       a1083_ind_admin = ?, \n");
			sql.append("       a1083_ind_desenv = ?, \n");
			sql.append("       a1083_ind_integrador = ?, \n");
			sql.append("       a1083_ind_aprovador = ?, \n");
			sql.append("       a1083_ind_testador = ?, \n");
			sql.append("       a1083_ind_dba = ?, \n");
			sql.append("       a1083_ind_po = ?, \n");
			sql.append("       a1083_dt_atz = ?, \n");
			sql.append("       a0015_cod_agente_atz = ? \n");
			sql.append(" WHERE a0015_cod_agente = ? \n");

			// params.add(new InParam(params.size() + 1, usuario.getNmeUsuarioSvn(), ParamType.VARCHAR));
			// params.add(new InParam(params.size() + 1, usuario.getDesEmail(), ParamType.VARCHAR));
			// params.add(new InParam(params.size() + 1, usuario.getDesSenha(), ParamType.VARCHAR));
			// params.add(new InParam(params.size() + 1, usuario.getAdmin(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getDesenvolvedor(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getIntegrador(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getAprovador(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getTestador(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getDba(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getPo(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, new Date(), ParamType.TIMESTAMP));
			// params.add(new InParam(params.size() + 1, usuario.getUsuarioLogado().getId(), ParamType.NUMERIC));
			// params.add(new InParam(params.size() + 1, usuario.getId(), ParamType.NUMERIC));

			executarUpdate(sql, params);

		}
		return cliente;
	}

	@Override
	public List<String> autoComplete(String texto) {
		final List<InParam> params = new ArrayList<InParam>();

		final StringBuffer sql = new StringBuffer();
		sql.append("SELECT nome \n");
		sql.append("  FROM cliente \n");
		sql.append(" WHERE UPPER(nome) like UPPER(?)  \n");
		params.add(new InParam(params.size() + 1, "%" + texto.toUpperCase() + "%", ParamType.VARCHAR));
		return executarQuery(sql, params, new IConverter<String>() {

			@Override
			public String convert(final ItemResultset reg) {
				return reg.getString("nome");
			}
		});
	}

	@Override
	public List<Cliente> autoCompleteObjeto(String texto) {
		final List<InParam> params = new ArrayList<InParam>();

		final StringBuffer sql = new StringBuffer();
		sql.append("SELECT nome \n");
		sql.append("  FROM cliente \n");
		sql.append(" WHERE UPPER(nome) like UPPER(?)  \n");
		params.add(new InParam(params.size() + 1, "%" + texto.toUpperCase() + "%", ParamType.VARCHAR));
		return executarQuery(sql, params, new IConverter<Cliente>() {

			@Override
			public Cliente convert(final ItemResultset reg) {
				final Cliente ret = new Cliente();
				ret.setId(reg.getLong("id"));
				
				ret.setDtaInclusao(reg.getDate("dt_inclusao"));
				ret.setDtaAlteracao(reg.getDate("dt_alteracao"));
//				ret.setUsuarioInclusao(reg.getLong("id_usuario_inclusao"));
//				ret.setUsuarioInclusao(reg.get);
//				ret.setAtivo(reg.getBoolean("ativo"));
//				ret.setNome(reg.getString("nome"));
//				ret.setCpf(reg.getString(columnName));
				return ret;
			}
			
//				id bigserial NOT NULL,
//			  dt_inclusao date NOT NULL,
//			  dt_alteracao date,
//			  id_usuario_inclusao bigint NOT NULL,
//			  id_usuario_alteracao bigint,
//			  ativo boolean NOT NULL DEFAULT false,
//			  cpf character varying(11),
//			  rg character varying(11),
//			  nome character varying(256) NOT NULL,
//			  sexo integer,
//			  tel_celular character varying(11),
//			  tel_comercial character varying(11),
//			  tel_residencial character varying(11),
//			  email character varying(256),
			
		});
	}
}
